package com.qf.controller;

import com.auth0.jwt.JWT;
import com.qf.aop.annocation.LoginToken;
import com.qf.constants.CacheConstants;
import com.qf.entity.Car;
import com.qf.entity.Email;
import com.qf.entity.ResultEntity;
import com.qf.entity.User;
import com.qf.feign.api.ICacheService;
import com.qf.feign.api.ICarCacheService;
import com.qf.feign.api.ICarMySQLService;
import com.qf.feign.api.IUserService;
import com.qf.utils.DeCodeUtils;
import com.qf.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math.random.RandomDataImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/sso")
@Slf4j
public class SSOController {

    @Autowired
    private IUserService userService;

    @Autowired
    private ICarCacheService cacheService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ICarMySQLService carMySQLService;

    @Value("${emailChange}")
    private String exchange;

    @RequestMapping("/checkUsername")
    public Map<String, String> checkUsername(String param) {

        Map<String, String> map = new HashMap<>();
        map.put("status", "n");
        map.put("info", "该用户名已被注册");

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("username", param);
        User user = userService.checkUser(paramMap);
        if (user == null) {
            map.put("status", "y");
            map.put("info", "可以注册");
        }
        return map;
    }


    @RequestMapping("/inputUsername")
    public Map<String, String> inputUsername(String param) {

        Map<String, String> map = new HashMap<>();
        map.put("status", "n"); //
        map.put("info", "用户不存在");

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("username", param);
        User user = userService.checkUser(paramMap);
        log.info("user:" + user);
        if (user != null) {
            map.put("status", "y");
            map.put("info", "用户存在");
        }
        return map;
    }


    @RequestMapping("/sendEmail")
    public ResultEntity sendEmail(String email) {

        if (!StringUtils.isEmpty(email)) {

            // 1.验证这个email是否已经被注册了
            Map<String, Object> map = new HashMap<>();
            map.put("email", email);

            // 2.查询邮箱是否已经被注册
            User user = userService.checkUser(map); // 如果存在返回的true

            // 3.如果返回的success，说明邮箱没有被注册
            if (user == null) {

                // 生成验证码
                int code = new RandomDataImpl().nextInt(1000, 9999);

                // 保存到reids
                // key=email_token，避免了其他业务模块也使用email作为key
                cacheService.set(email + CacheConstants.REGISTER_TOKEN, code + "", 15L);

                // 4.封装邮件的信息
                Email email1 = new Email();
                email1.setSubject("千锋2002商城注册");
                email1.setContent("验证码:" + code);
                email1.setTo(email);

                // 5.发送邮件
                rabbitTemplate.convertAndSend(exchange, "email.send", email1);

                // 6.邮件发送成功
                return ResultEntity.success();
            } else {
                // 返回邮箱已经被注册
                return ResultEntity.error("邮箱已被注册");
            }
        }
        return ResultEntity.error("邮箱为空");
    }

    @RequestMapping("registerUser")
    public ResultEntity registerUser(User user, String code) {
        log.debug(code);
        log.debug(user.toString());

        // 1.判断验证码是否正确
        // 1.1. 先根据用户的邮箱查询到验证码
        String redisCode = cacheService.get(user.getEmail() + CacheConstants.REGISTER_TOKEN);

        // 2.判断验证码是否为空
        if (StringUtils.isEmpty(redisCode)) {
            return ResultEntity.error("验证码以过期，重新发送");
        }

        // 3.判断用户输入的验证码和redis中查询的验证码是否一致
        if (!redisCode.equals(code)) {
            return ResultEntity.error("验证码有误");
        }


        // 对密码加密
        String hashpw = DeCodeUtils.hashpw(user.getPassword());
        user.setPassword(hashpw);

        // 4.注册
        ResultEntity resultEntity = userService.addUser(user);
        if (ResultEntity.SUCEESS.equals(resultEntity.getStatus())) {
            return ResultEntity.success("注册成功");
        } else {
            return ResultEntity.error("注册失败");
        }
    }

    @RequestMapping("login")
    public ResultEntity login(String username,
                              String password,
                              @CookieValue(name = CacheConstants.CAR_TOKEN ,required = false)String carToken,
                              HttpServletResponse response) {

        // 1.根据用户名查询用户
        User user = userService.getUserByUsername(username);

        if (user == null) {
            return ResultEntity.error("用户不存在");
        }

        // 2.密码的不对
        if (!DeCodeUtils.checkpw(password, user.getPassword())) {
            return ResultEntity.error("用户名获密码错误。。。");
        }
        ;

        // 3.生成看token
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("id", user.getId().toString());
        tokenMap.put("username", user.getUsername().toString());
        String token = JWTUtils.createToken(tokenMap, null);


        // 4.合并购物车(把Redis中的额数据放入到MySQL)中
        if(!StringUtils.isEmpty(carToken)){
            List<Car> userCarList = cacheService.getUserCarList(carToken);
            if(!userCarList.isEmpty()){

                // 同步到MySQL中
                for (Car car : userCarList) {
                    car.setUid(user.getId()); // 设置uid
                }

                // 把购物车添加MySQL
                carMySQLService.batchAddCar(userCarList);

                // 删除用户在reids中的购物车
                cacheService.del(carToken);

                // 干掉cookie
                Cookie cookie = new Cookie(CacheConstants.CAR_TOKEN,"");
                cookie.setMaxAge(-1);
                cookie.setPath("/");
                response.addCookie(cookie);
            }
        }

        // 4.响应数据
        return ResultEntity.success(token);
    }

    // getUserById/10 10--消费--》User--》
    @RequestMapping(value = "sendEmailChangePassoword", produces = "text/html;charset=utf-8")
    public String sendEmailChangePassoword(String username) {

        // 1.根据用户名查询邮箱
        Map<String, Object> map = new HashMap<>();
        map.put("username", username);
        User user = userService.checkUser(map);

        // 2.判断
        if (user != null) {

            // 3.获取邮箱
            // 854569279@qq.com
            // 854569279@163.com
            // 854569279@qf.com
            String email = user.getEmail();


            Map<String, String> tokenMap = new HashMap<>();
            tokenMap.put("id", user.getId().toString());
            String token = JWTUtils.createToken(tokenMap, 60 * 30);

            // 4.封装邮件对象
            Email email1 = new Email();
            email1.setSubject("2002-sohp用户密码修改");
            email1.setContent("<h1> <a href='http://localhost/shop-sso/toChangePasswordPage?token=" + token + "'>点击这里修改密码</a></h1>");
            email1.setTo(email);

            // 5.发送邮件
            rabbitTemplate.convertAndSend(exchange, "email.send", email1);

            // 6.响应用户
            // https://mail.163.com/
            String fix = email.substring(email.lastIndexOf("@") + 1);
            String mailUrl = "http://mail." + fix;
            return "修改密码的连接已经发送到你的邮箱，点击<a href='" + mailUrl + "'>这里</a>登录邮箱查看";
        }

        return null;
    }

    @RequestMapping("/updatePassword")
    public ResultEntity updatePassword(String password, String token) {

        // 1.验证token
        ResultEntity resultEntity = JWTUtils.require(token);
        if (ResultEntity.SUCEESS.equals(resultEntity.getStatus())) {

            // 2.从token中获取userid
            String id = JWTUtils.getClaim(token, "id");

            // 3.修改密码
            String hashpw = DeCodeUtils.hashpw(password); // 加密

            userService.updatePassowrd(hashpw, Integer.parseInt(id));

            // 4.提示用户修改成功
            return ResultEntity.success("修改成功");

        } else {
            return ResultEntity.error(resultEntity.getMsg());
        }
    }

    @LoginToken
    @RequestMapping("/isLogin")
    public ResultEntity isLogin(User user) {
        if(user != null){
            return ResultEntity.success(user);
        }else{
            return ResultEntity.error("没有登录");
        }
    }

    @RequestMapping("/logout")
    public ResultEntity logout() {
        log.info("logout");
        return null;
    }

}
